#include <jni.h>
#include "string"
#include "SnClientDll.h"

using namespace std;
JNIEnv *globleEnv;

typedef long LONG;
#define DWORD unsigned long
typedef struct {
    bool bFirst;
    string sSessionId;
    long nCmdType;         //命令类型
    long nAKey;
    long nSID;
    bool bQuit;                      //停止
    long PlatFormLogonID;            //登陆句柄
} CALLBACKDATA;  //存放同一通道多窗口播放的信息
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env = NULL;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
        return JNI_ERR;
    }
    globleEnv = env;
//    jclass cls = env->FindClass("LRegisterNativesTest;");
//    if (cls == NULL)
//    {
//        return JNI_ERR;
//    }
//
//    int len = sizeof(s_methods) / sizeof(s_methods[0]);
//    if (env->RegisterNatives(cls, s_methods, len) < 0)
//    {
//        return JNI_ERR;
//    }

    return JNI_VERSION_1_4;
}

JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
    globleEnv = NULL;
}

//jstring to char*
char *jstringTostring(JNIEnv *env, jstring jstr) {
    char *rtn = NULL;
    jclass clsstring = env->FindClass("java/lang/String");
    jstring strencode = env->NewStringUTF("utf-8");
    jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
    jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
    jsize alen = env->GetArrayLength(barr);
    jbyte *ba = env->GetByteArrayElements(barr, JNI_FALSE);
    if (alen > 0) {
        rtn = (char *) malloc(alen + 1);
        memcpy(rtn, ba, alen);
        rtn[alen] = 0;
    }
    env->ReleaseByteArrayElements(barr, ba, 0);
    return rtn;
}

//char* to jstring
jstring stoJstring(JNIEnv *env, const char *pat) {
    jclass strClass = env->FindClass("Ljava/lang/String;");
    jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
    jbyteArray bytes = env->NewByteArray(strlen(pat));
    env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte *) pat);
    jstring encoding = env->NewStringUTF("utf-8");
    return (jstring) env->NewObject(strClass, ctorID, bytes, encoding);
}

jobject aUserContext2Class(void *aUserContext) {
    if (aUserContext) {
        CALLBACKDATA *context = (CALLBACKDATA *) aUserContext;
        jclass pJclass = globleEnv->FindClass("com/edu/videosurveillance/bean/UserContext");
        jmethodID init = globleEnv->GetMethodID(pJclass, "<init>", "()V");
        jobject object = globleEnv->NewObject(pJclass, init);
        jfieldID bFirst = globleEnv->GetFieldID(pJclass, "bFirst", "Z");
        jfieldID sSessionId = globleEnv->GetFieldID(pJclass, "sSessionId", "Ljava/lang/String;");
        jfieldID nCmdType = globleEnv->GetFieldID(pJclass, "nCmdType", "J");
        jfieldID nAKey = globleEnv->GetFieldID(pJclass, "nAKey", "J");
        jfieldID nSID = globleEnv->GetFieldID(pJclass, "nSID", "J");
        jfieldID bQuit = globleEnv->GetFieldID(pJclass, "bQuit", "Z");
        jfieldID PlatFormLogonID = globleEnv->GetFieldID(pJclass, "PlatFormLogonID", "J");
        globleEnv->SetBooleanField(object, bFirst, context->bFirst);
        globleEnv->SetObjectField(object, sSessionId,
                                  globleEnv->NewStringUTF(context->sSessionId.data()));
        globleEnv->SetLongField(object, nCmdType, context->nCmdType);
        globleEnv->SetLongField(object, nAKey, context->nAKey);
        globleEnv->SetLongField(object, nSID, context->nSID);
        globleEnv->SetBooleanField(object, bQuit, context->bQuit);
        globleEnv->SetLongField(object, PlatFormLogonID, context->PlatFormLogonID);
        return object;
    }
    return NULL;
}

CALLBACKDATA *class2UserContext(JNIEnv *env, jobject context) {
    if (context != NULL) {
        CALLBACKDATA *aUserContext = new CALLBACKDATA();
        jclass pJclass = env->GetObjectClass(context);
        jfieldID bFirst = env->GetFieldID(pJclass, "bFirst", "Z");
        jfieldID sSessionId = env->GetFieldID(pJclass, "sSessionId", "Ljava/lang/String;");
        jfieldID nCmdType = env->GetFieldID(pJclass, "nCmdType", "J");
        jfieldID nAKey = env->GetFieldID(pJclass, "nAKey", "J");
        jfieldID nSID = env->GetFieldID(pJclass, "nSID", "J");
        jfieldID bQuit = env->GetFieldID(pJclass, "bQuit", "Z");
        jfieldID PlatFormLogonID = env->GetFieldID(pJclass, "PlatFormLogonID", "J");
        aUserContext->bFirst = env->GetBooleanField(context, bFirst);
        jstring str = (jstring) env->GetObjectField(context, sSessionId);
        aUserContext->sSessionId = jstringTostring(env, str);
        aUserContext->nCmdType = env->GetLongField(context, nCmdType);
        aUserContext->nAKey = env->GetLongField(context, nAKey);
        aUserContext->nSID = env->GetLongField(context, nSID);
        aUserContext->bQuit = env->GetBooleanField(context, bQuit);
        aUserContext->PlatFormLogonID = env->GetLongField(context, PlatFormLogonID);
        return aUserContext;
    }
    return NULL;
}

/**
 * 将结构体TLogOnInfo转换为java对象
 */
jobject TLogOnInfo2Class(JNIEnv *env, TLogOnInfo *logOnInfo, jobject mUserInfo) {
    jclass jUserInfo;
    if (mUserInfo == NULL) {
        jUserInfo = env->FindClass("com/edu/videosurveillance/bean/UserInfo");
        jmethodID init = env->GetMethodID(jUserInfo, "<init>", "()V");
        mUserInfo = env->NewObject(jUserInfo, init);
    } else
        jUserInfo = env->GetObjectClass(mUserInfo);
    jfieldID AppVersion = env->GetFieldID(jUserInfo, "AppVersion", "Ljava/lang/String;");
    env->SetObjectField(mUserInfo, AppVersion, stoJstring(env, logOnInfo->AppVersion));
    jfieldID AppName = env->GetFieldID(jUserInfo, "AppName", "Ljava/lang/String;");
    env->SetObjectField(mUserInfo, AppName, stoJstring(env, logOnInfo->AppName));
    jfieldID AppUser = env->GetFieldID(jUserInfo, "AppUser", "Ljava/lang/String;");
    env->SetObjectField(mUserInfo, AppUser, stoJstring(env, logOnInfo->AppUser));
    jfieldID MaxChannelNumber = env->GetFieldID(jUserInfo, "MaxChannelNumber",
                                                "Ljava/lang/String;");
    env->SetObjectField(mUserInfo, MaxChannelNumber, stoJstring(env, logOnInfo->MaxChannelNumber));
    jfieldID ParamDate = env->GetFieldID(jUserInfo, "ParamDate", "Ljava/lang/String;");
    env->SetObjectField(mUserInfo, ParamDate, stoJstring(env, logOnInfo->ParamDate));
    jfieldID SysDate = env->GetFieldID(jUserInfo, "SysDate", "Ljava/lang/String;");
    env->SetObjectField(mUserInfo, SysDate, stoJstring(env, logOnInfo->SysDate));
    jfieldID PerId = env->GetFieldID(jUserInfo, "PerId", "Ljava/lang/String;");
    env->SetObjectField(mUserInfo, PerId, stoJstring(env, logOnInfo->PerId));
    jfieldID PerName = env->GetFieldID(jUserInfo, "PerName", "Ljava/lang/String;");
    env->SetObjectField(mUserInfo, PerName, stoJstring(env, logOnInfo->PerName));
    return mUserInfo;
}

jobject TSearchCondition2Class(JNIEnv *env, TSearchCondition *tSearchCondition) {
    if (tSearchCondition != NULL) {
        jclass pJClass = env->FindClass("com/edu/videosurveillance/bean/TSearchCondition");
        jmethodID init = env->GetMethodID(pJClass, "<init>",
                                          "(Ljava/lang/String;Ljava/lang/String;CCCLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;C)V");
        jobject object = env->NewObject(pJClass, init, stoJstring(env, tSearchCondition->StartTime),
                                        stoJstring(env, tSearchCondition->EndTime),
                                        tSearchCondition->AlarmState, tSearchCondition->AlarmType,
                                        tSearchCondition->AlarmLevel,
                                        stoJstring(env, tSearchCondition->PosiName),
                                        stoJstring(env, tSearchCondition->ParentDevName),
                                        stoJstring(env, tSearchCondition->DevName),
                                        stoJstring(env, tSearchCondition->RecPerName),
                                        stoJstring(env, tSearchCondition->AlarmTypes),
                                        stoJstring(env, tSearchCondition->AlarmChildType),
                                        tSearchCondition->IsMerged);
        return object;
    }
    return NULL;
}

TSearchCondition *class2TSearchCondition(JNIEnv *env, jobject object) {
    if (object == NULL)
        return NULL;
    TSearchCondition *tSearchCondition = new TSearchCondition();
    jclass pJClass = env->GetObjectClass(object);
    jfieldID startTime = env->GetFieldID(pJClass, "StartTime", "Ljava/lang/String;");
    char *jStartTime = jstringTostring(env, (jstring) env->GetObjectField(object, startTime));
    strncpy(tSearchCondition->StartTime, jStartTime, MAX_Field_LEN);

    jfieldID EndTime = env->GetFieldID(pJClass, "EndTime", "Ljava/lang/String;");
    char *jEndTime = jstringTostring(env, (jstring) env->GetObjectField(object, EndTime));
    strncpy(tSearchCondition->StartTime, jEndTime, MAX_Field_LEN);

    jfieldID AlarmState = env->GetFieldID(pJClass,"AlarmState","C");
    tSearchCondition->AlarmState = env->GetCharField(object,AlarmState);

    jfieldID AlarmType = env->GetFieldID(pJClass,"AlarmType","C");
    tSearchCondition->AlarmType = env->GetCharField(object,AlarmType);
    
    jfieldID AlarmLevel = env->GetFieldID(pJClass,"AlarmLevel","C");
    tSearchCondition->AlarmLevel = env->GetCharField(object,AlarmLevel);
    
    jfieldID PosiName = env->GetFieldID(pJClass, "PosiName", "Ljava/lang/String;");
    char *jPosiName = jstringTostring(env, (jstring) env->GetObjectField(object, PosiName));
    strncpy(tSearchCondition->PosiName, jPosiName, MAX_Field_LEN);
    
    jfieldID ParentDevName = env->GetFieldID(pJClass, "ParentDevName", "Ljava/lang/String;");
    char *jParentDevName = jstringTostring(env, (jstring) env->GetObjectField(object, ParentDevName));
    strncpy(tSearchCondition->StartTime, jParentDevName, MAX_Field_LEN);
    
    jfieldID DevName = env->GetFieldID(pJClass, "DevName", "Ljava/lang/String;");
    char *jDevName = jstringTostring(env, (jstring) env->GetObjectField(object, DevName));
    strncpy(tSearchCondition->StartTime, jDevName, MAX_Field_LEN);
    
    jfieldID RecPerName = env->GetFieldID(pJClass, "RecPerName", "Ljava/lang/String;");
    char *jRecPerName = jstringTostring(env, (jstring) env->GetObjectField(object, RecPerName));
    strncpy(tSearchCondition->StartTime, jRecPerName, MAX_Field_LEN);

    jfieldID AlarmTypes = env->GetFieldID(pJClass, "AlarmTypes", "Ljava/lang/String;");
    char *jAlarmTypes = jstringTostring(env, (jstring) env->GetObjectField(object, AlarmTypes));
    strncpy(tSearchCondition->StartTime, jAlarmTypes, MAX_Field_LEN);
    
    jfieldID AlarmChildType = env->GetFieldID(pJClass, "AlarmChildType", "Ljava/lang/String;");
    char *jAlarmChildType = jstringTostring(env, (jstring) env->GetObjectField(object, AlarmChildType));
    strncpy(tSearchCondition->StartTime, jAlarmChildType, MAX_Field_LEN);
    
    jfieldID IsMerged = env->GetFieldID(pJClass,"IsMerged","C");
    tSearchCondition->IsMerged = env->GetCharField(object,IsMerged);

    return tSearchCondition;
}
/*--------------------------------------JNI以及java回调方法----------------------------------------------------------*/
JNIEXPORT void JNICALL
Java_com_edu_videosurveillance_JniHelper_createInstance(JNIEnv *env, jclass type) {
    // TODO
    SnClient_CreateInstance();
}

JNIEXPORT void JNICALL
Java_com_edu_videosurveillance_JniHelper_destoryInstance(JNIEnv *env, jclass type) {

    // TODO
    SnClient_DestroyInstance();
}

JNIEXPORT void JNICALL
Java_com_edu_videosurveillance_JniHelper_setHeartbeatEvent(JNIEnv *env, jclass type,
                                                           jobject mContext) {
    // TODO
    SnClient_SetHeartbeatEvent(&javaPOnHeartbeatEvent, class2UserContext(env, mContext));
}

/**
 * 调用java层的回调方法
 */
void javaPOnHeartbeatEvent(long lUserId, long lState, long lErrCode, void *aUserContext) {
    if (aUserContext) {//*aUserContext不为空
        if (globleEnv) {
            jclass helper = (globleEnv)->FindClass("com/edu/videosurveillance/JniHelper");
            if (helper != NULL) {
                jmethodID method = globleEnv->GetMethodID(helper, "pOnHeartbeatEvent",
                                                          "(JJJLcom/edu/videosurveillance/bean/UserContext;)V");
                if (method != NULL) {
                    globleEnv->CallStaticVoidMethod(helper, method, lUserId, lState, lErrCode,
                                                    aUserContext2Class(aUserContext));
                }
            };
        }
    }
}

JNIEXPORT void JNICALL
Java_com_edu_videosurveillance_JniHelper_setAlarmEvent(JNIEnv *env, jclass type, jlong lInfoFormat,
                                                       jobject mContext) {
    // TODO
    SnClient_SetAlarmEvent(lInfoFormat, &javaPAlarmMessageEvent, class2UserContext(env, mContext));
}

/**
 * 调用java层的报警回调方法
 */
void javaPAlarmMessageEvent(long lUserId,            //用户登录平台返回的会话句柄
                            long lInfoType,            //报警内容内容格式
                            void *aInfoData,        //报警内容数据指针
                            long lInfoDataLen,        //报警内容数据大小
                            void *aUserContext) {
    jclass helper = (globleEnv)->FindClass("com/edu/videosurveillance/JniHelper");
    if (helper != NULL) {
        jmethodID method = globleEnv->GetMethodID(helper, "pAlarmMessageEvent",
                                                  "(JJLjava/lang/String;JLcom/edu/videosurveillance/bean/UserContext;)V");
        if (method != NULL) {
            globleEnv->CallStaticVoidMethod(helper, method, lUserId, lInfoType,
                                            globleEnv->NewStringUTF((char *) aInfoData),
                                            lInfoDataLen,
                                            aUserContext2Class(aUserContext));
        }
    };
}

JNIEXPORT void JNICALL
Java_com_edu_videosurveillance_JniHelper_setSourceUpDataEvent(JNIEnv *env, jclass type,
                                                              jlong lMsgFormat, jobject mContext) {
    // TODO
    SnClient_SetSourceUpDataEvent(lMsgFormat, &javaPUpDataEvent, class2UserContext(env, mContext));
}

void javaPUpDataEvent(long lUserId,        //用户登录平台返回的会话句柄
                      long lSourceType,    //资源类型
                      void *aUpData,        //资源内容指针
                      long lUpDataLen,        //资源内容大小
                      void *aUserContext) {    //上下文指针
    jclass helper = (globleEnv)->FindClass("com/edu/videosurveillance/JniHelper");
    if (helper != NULL) {
        jmethodID method = globleEnv->GetMethodID(helper, "pUpDataEvent",
                                                  "(JJLjava/lang/String;JLcom/edu/videosurveillance/bean/UserContext;)V");
        if (method != NULL) {
            globleEnv->CallStaticVoidMethod(helper, method, lUserId, lSourceType,
                                            globleEnv->NewStringUTF((char *) aUpData),
                                            lUpDataLen,
                                            aUserContext2Class(aUserContext));
        }
    };
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_login(JNIEnv *env, jclass type, jstring ip_, jlong port_,
                                               jstring account_, jstring password_, jboolean md5,
                                               jobject mUserInfo) {
    TLogOnInfo *logOnInfo = new TLogOnInfo();
    LONG result = SnClient_Logon(jstringTostring(env, ip_), port_, jstringTostring(env, account_),
                                 jstringTostring(env, password_), md5, logOnInfo);
    if (result >= 0) {//登录成功
        mUserInfo = TLogOnInfo2Class(env, logOnInfo, mUserInfo);
    }
    return result;
    // TODO
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_loginAsync(JNIEnv *env, jclass type, jstring ip_,
                                                    jlong port_, jstring account_,
                                                    jstring password_, jboolean md5,
                                                    jobject aUserContext) {
    // TODO
    return SnClient_AsynLogon(jstringTostring(env, ip_), port_, jstringTostring(env, account_),
                              jstringTostring(env, password_), md5, &javaPLogonCallBack,
                              class2UserContext(env, aUserContext));
}

/**
 * 平台异步登录回调函数,会调用java端方法
 */
void javaPLogonCallBack(long lUserId, long lResultCode, PLogOnInfo pstLogOnInfo,
                        void *aUserContext) {
    jclass helper = (globleEnv)->FindClass("com/edu/videosurveillance/JniHelper");
    if (helper != NULL) {
        jmethodID method = globleEnv->GetMethodID(helper, "pUpDataEvent",
                                                  "(JJLjava/lang/String;JLcom/edu/videosurveillance/bean/UserInfo;)V");
        jobject jUserInfo = TLogOnInfo2Class(globleEnv, pstLogOnInfo, NULL);
        if (method != NULL) {
            globleEnv->CallStaticVoidMethod(helper, method, lUserId, lResultCode, jUserInfo,
                                            aUserContext2Class(aUserContext));
        }
    };
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_logout(JNIEnv *env, jclass type, jlong lUserId) {
    // TODO
    return SnClient_Logout(lUserId);
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_setGetSourceCallBack(JNIEnv *env, jclass type,
                                                              jlong lUserId, jobject mContext) {
    // TODO
    return SnClient_SetGetSourceCallBack(lUserId, &javaGetSourceCallBack,
                                         class2UserContext(env, mContext));
}

void javaGetSourceCallBack(LONG lUserId, LONG lSourceType, LONG lErrCode, void *aParaIn,
                           LONG lParaInLen, void *aUserContext) {
    jclass helper = (globleEnv)->FindClass("com/edu/videosurveillance/JniHelper");
    if (helper != NULL) {
        jmethodID method = globleEnv->GetMethodID(helper, "pGetTredPro",
                                                  "(JJJLjava/lang/String;JLcom/edu/videosurveillance/bean/UserContext;)V");
        if (method != NULL) {
            globleEnv->CallStaticVoidMethod(helper, method, lUserId, lSourceType, lErrCode,
                                            globleEnv->NewStringUTF((char *) aParaIn),
                                            lParaInLen,
                                            aUserContext2Class(aUserContext));
        }
    };
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_getSource(JNIEnv *env, jclass type, jlong lUserId,
                                                   jlong lSourceType) {
    // TODO
    return SnClient_GetSource(lUserId, lSourceType);
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_SetArming(JNIEnv *env, jclass type, jlong lUserId) {

    // TODO
    return SnClient_SetArming(lUserId);
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_SetUnArming(JNIEnv *env, jclass type, jlong lUserId) {
    // TODO
    return SnClient_SetUnArming(lUserId);
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_getAlarmCount(JNIEnv *env, jclass type, jlong lUserId,
                                                       jobject stSearchCondition) {
    // TODO
    TSearchCondition *searchCondition = class2TSearchCondition(env,stSearchCondition);
    return SnClient_GetAlarmCount(lUserId,*searchCondition);
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_getAlarmList(JNIEnv *env, jclass type, jlong lUserId,
                                                      jobject stSearchCondition, jlong lStartline,
                                                      jlong lEndLine, jobject mContext) {
    // TODO
    TSearchCondition *searchCondition = class2TSearchCondition(env,stSearchCondition);
    return SnClient_GetAlarmList(lUserId,*searchCondition,lStartline,lEndLine,&javaGetAlarmListCallBack,class2UserContext(env,mContext));
}

void javaGetAlarmListCallBack(LONG lUserId, LONG lParamType, LONG lErrCode, void *aParaIn,	LONG lParaInLen,void *aUserContext) {
    jclass helper = (globleEnv)->FindClass("com/edu/videosurveillance/JniHelper");
    if (helper != NULL) {
        jmethodID method = globleEnv->GetMethodID(helper, "pGetAlarmPro",
                                                  "(JJJLjava/lang/String;JLcom/edu/videosurveillance/bean/UserContext;)V");
        if (method != NULL) {
            globleEnv->CallStaticVoidMethod(helper, method, lUserId, lParamType, lErrCode,
                                            globleEnv->NewStringUTF((char *) aParaIn),
                                            lParaInLen,
                                            aUserContext2Class(aUserContext));
        }
    };
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_getStream_1Start(JNIEnv *env, jclass type, jlong lUserId,
                                                          jstring sChannelId_, jlong lStreamType,
                                                          jobject mContext) {
    // TODO
    return SnClient_GetStream_Start(lUserId,jstringTostring(env,sChannelId_),lStreamType,&javaGetStreamRet,&javaStreamCallBack,class2UserContext(env,mContext));
}
//CSDK预览结果回调的函数,主要用于出错的时候，得到出差的具体原因
void javaGetStreamRet(	   LONG lUserId,			  //登录句柄
                             LONG lStreamId,			  //预览句柄；
                             LONG lParamType,			  //参数类型
                             LONG lErrCode,			  // 错误码
                             TDeviceInfo stDeviceInfo,  //设备基础信息
                             void *aUserContext         //上下文指针
)
{

}
void javaStreamCallBack(	 LONG lUserId,			  // 用户登录平台返回的会话句柄
                             LONG lStreamId,          //预览句柄；
                             DWORD dwDataType,        //数据播放类型(0=头数据，1=流数据)
                             char *pBuffer,           //流数据缓冲区
                             DWORD dwBufSize,         //流数据大小
                             DWORD dwFrameType,       //数据类型5：视频6：音频
                             LONG iKey,               //帧类型0：I帧2：P帧
                             TimEx stDevData,              //设备时间
                             void *aUserContext      //上下文指针
)
{
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_getStream_1Stop(JNIEnv *env, jclass type, jlong lStreamId) {

    // TODO
    SnClient_GetStream_Stop(lStreamId);
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_getAlarmLinkageInfo(JNIEnv *env, jclass type,
                                                             jlong lUserId, jstring sAlarmId_,
                                                             jobject pstAlarmLinkageInfo) {
    const char *sAlarmId = env->GetStringUTFChars(sAlarmId_, 0);

    // TODO

    env->ReleaseStringUTFChars(sAlarmId_, sAlarmId);
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_handleAlarm(JNIEnv *env, jclass type, jlong lUserId,
                                                     jstring sAlarnID_, jlong lHandelType,
                                                     jstring aParma_, jlong lParamLen) {

}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_batchHandleAlarm(JNIEnv *env, jclass type, jlong lUserId,
                                                          jstring aAlarmIDs_, jlong lAlarmIDsLen,
                                                          jstring aParam_, jlong lParamLen) {
    const char *aAlarmIDs = env->GetStringUTFChars(aAlarmIDs_, 0);
    const char *aParam = env->GetStringUTFChars(aParam_, 0);

    // TODO

    env->ReleaseStringUTFChars(aAlarmIDs_, aAlarmIDs);
    env->ReleaseStringUTFChars(aParam_, aParam);
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_batchHandleGroupAlarm(JNIEnv *env, jclass type,
                                                               jlong lUserId, jlong lListType,
                                                               jstring pDevIDs_, jlong lDevIDsLen,
                                                               jstring pAlarmTypeIDs_,
                                                               jlong lAlarmTypeIDsLen,
                                                               jstring aParam_, jlong lParamLen) {
    const char *pDevIDs = env->GetStringUTFChars(pDevIDs_, 0);
    const char *pAlarmTypeIDs = env->GetStringUTFChars(pAlarmTypeIDs_, 0);
    const char *aParam = env->GetStringUTFChars(aParam_, 0);

    // TODO

    env->ReleaseStringUTFChars(pDevIDs_, pDevIDs);
    env->ReleaseStringUTFChars(pAlarmTypeIDs_, pAlarmTypeIDs);
    env->ReleaseStringUTFChars(aParam_, aParam);
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_getPictureFileListCount(JNIEnv *env, jclass type,
                                                                 jlong lUserID, jstring sChannelID_,
                                                                 jlong lFileType,
                                                                 jstring sStartTime_,
                                                                 jstring sEndTime_,
                                                                 jlong lFileCount) {

    // TODO
}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_getPictureFileList(JNIEnv *env, jclass type,
                                                            jlong lFileListId,
                                                            jobjectArray pPictureList) {

    // TODO

}

JNIEXPORT jlong JNICALL
Java_com_edu_videosurveillance_JniHelper_pictureDownload(JNIEnv *env, jclass type, jlong lUserID,
                                                         jstring sChannelID_,
                                                         jstring sPicFileName_) {
}